﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Ionic.Zip;
using System.IO;

namespace DBLoader
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            _openFileDialogMMO.InitialDirectory = "C:\\";
            _openFileDialogMMO.Filter = "MMO files (*.mmo)|*.mmo";
            _openFileDialogMMO.Multiselect = true;
            _openFileDialogMMO.RestoreDirectory = true;
            _FolderBrowserDialogCF.RootFolder = System.Environment.SpecialFolder.Desktop;
            if (!File.Exists("ConvertedMMO.txt"))
            {
                File.Create("ConvertedMMO.txt");
            }
            if (!File.Exists("SentToSagem.txt"))
            {
                File.Create("SentToSagem.txt");
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void BrowseButton_Click(object sender, EventArgs e)
        {
            _openFileDialogMMO.ShowDialog();
        }

        

        private void _openFileDialog_FileOk(object sender, CancelEventArgs e)
        {
            String PartName;
            foreach (String FileName in _openFileDialogMMO.FileNames)
            {
                int NameID = FileName.LastIndexOf('\\');
                PartName = FileName.Remove(0, NameID+1);
                if (FullFileNamesMMO.Contains(FileName))
                {
                    MessageBox.Show("File " + PartName + " is already selected");
                }
                else
                {
                    FullFileNamesMMO.Add(FileName);
                    ProcessingFile.Items.Add(PartName);
                }
            }
        }

        private void DeleteItemFromMmoLists(int ID)
        {
            ProcessingFile.Items.RemoveAt(ID);
            FullFileNamesMMO.RemoveAt(ID);
            ProcessingFile.Refresh();
        }

        private void DeleteButton_Click(object sender, EventArgs e)
        {
            int RemID = ProcessingFile.SelectedIndex;
            if (RemID >= 0)
            {
                DeleteItemFromMmoLists(RemID);
            }
        }

        public void AddIntoConvertedList(int ExitCode, String FileName, int Id, ProcessHandler caller)
        {
            lock(this)
            {
                if (ExitCode == 0)
                {
                    String FolderName = FileName.Remove(FileName.Length - 4);
                    FullFolderNamesCF.Add(FolderName);
                    int NameID = FolderName.LastIndexOf('\\');
                    String PartName = FolderName.Remove(0, NameID + 1);
                    AddTextToListConvertedMMO(PartName);
                    File.Delete(FolderName + ".mmo");
                    ConvertedMMO = new FileStream("ConvertedMMO.txt", FileMode.Append);
                    byte[] NameForLog = new UTF8Encoding(true).GetBytes((PartName + "\n\r"));
                    ConvertedMMO.Write(NameForLog, 0, NameForLog.Length);
                    ConvertedMMO.Close();
                    ListConvMMO2XML.Remove(caller);
                }
                else
                {
                    MessageBox.Show("Flight " + FileName + " was not converted.");
                }
            }
            
        }

        private delegate void stringDelegate(string s);

        private void RemoveTextFromMMOList(string FileName)
        {
            if (ProcessingFile.InvokeRequired)
            {
                stringDelegate sd = new stringDelegate(RemoveTextFromMMOList);
                ConvertedFolderList.Invoke(sd, new object[] { FileName });
                return;
            }
            int Id = ProcessingFile.Items.IndexOf(FileName);
            ProcessingFile.Items.Remove(FileName);
            FullFileNamesMMO.RemoveAt(Id);
 
        }

        private void AddTextToListConvertedMMO(string FolderName)
        {
            if (ConvertedFolderList.InvokeRequired)
            {
                stringDelegate sd = new stringDelegate(AddTextToListConvertedMMO);
                ConvertedFolderList.Invoke(sd, new object[] { FolderName });
                return;
            }
            ConvertedFolderList.Items.Add(FolderName);
        }

        private void ConvertButton_Click(object sender, EventArgs e)
        {
            int Id = ProcessingFile.SelectedIndex;
            if (Id >= 0)
            {
                string[] args = new string[2];
                BackgroundWorker _zipBW = new BackgroundWorker();
                _zipBW.DoWork += new DoWorkEventHandler(_zipBW_DoWork);
                args[0] = FullFileNamesMMO[Id];
                args[1] = args[0].Remove(args[0].Length - 4) + ".zip";
                _zipBW.RunWorkerAsync(args);
                ProcessHandler PrcHnd = new PythonProcessHandler(AddIntoConvertedList, ListConvMMO2XML.Count, FullFileNamesMMO[Id]);   //new PythonProcessHandler(this, ListConvMMO2XML.Count, FullFileNamesMMO[Id]);
                PrcHnd.Command = "python Convert.py " + PrcHnd.FileName;
                //ListConvMMO2XML.Add(PrcHnd);
                RemoveTextFromMMOList((string)ProcessingFile.Items[Id]);
                //ListConvMMO2XML[ListConvMMO2XML.Count - 1].RunProcess();
                PrcHnd.RunProcess();
            }
        }

        private void StartConversion(PythonProcessHandler.PostProcessing PostProc, int Id)
        {

        }

        private void _zipBW_DoWork(object sender, DoWorkEventArgs e)
        {
            string[] FileNames = (string[])e.Argument;
            ZipFile zip = new ZipFile();
            zip.AddFile(FileNames[0]);
            zip.Save(FileNames[1]);
        }

        private void sendToSagemButton_Click(object sender, EventArgs e)
        {
            int Id = ConvertedFolderList.SelectedIndex;
            if (Id >= 0)
            {
                ProcessHandler PrcHnd = new SagemProcessHandler(AppendToSagemLog, ListSend2Sagem.Count, FullFolderNamesCF[Id]);
                PrcHnd.Command = "java -jar media-express-link.jar -batch -path " + PrcHnd.FileName;
                //ListSend2Sagem.Add(PrcHnd);
                //ListSend2Sagem[ListSend2Sagem.Count - 1].RunProcess();
                PrcHnd.RunProcess();
            }
        }

        public void AppendToSagemLog(int ExitCode, String FileName, ProcessHandler caller)
        {
            lock (this)
            {
                if (ExitCode == 0)
                {
                    int NameID = FileName.LastIndexOf('\\');
                    String PartName = FileName.Remove(0, NameID + 1);
                    SendedToSagem = new FileStream("SentToSagem.txt", FileMode.Append);
                    byte[] NameForLog = new UTF8Encoding(true).GetBytes((PartName + "\r\n"));
                    SendedToSagem.Write(NameForLog, 0, NameForLog.Length);
                    SendedToSagem.Flush();
                    SendedToSagem.Close();
                    ListSend2Sagem.Remove(caller);
                }
                else
                {
                    MessageBox.Show("Flight " + FileName + " was not send to Sagem");
                }
            }
        }

        public void ShowMessage(string Msg)
        {
            lock (this)
            {
                MessageBox.Show(Msg);
            }
        }

        private void BrowseCFButton_Click(object sender, EventArgs e)
        {
            DialogResult res = _FolderBrowserDialogCF.ShowDialog();
            if (res == DialogResult.OK)
            {
                String CFpath = _FolderBrowserDialogCF.SelectedPath;
                if (FolderContainsXMLfile(CFpath))
                {
                    FullFolderNamesCF.Add(CFpath);
                    int NameID = CFpath.LastIndexOf('\\');
                    String PartName = CFpath.Remove(0, NameID + 1);
                    ConvertedFolderList.Items.Add(PartName);
                }
                else
                {
                    MessageBox.Show("Directory does not contain XML with specified name!");
                }
                
            }

        }

        private bool FolderContainsXMLfile(String FolderPath)
        {
            int NameID = FolderPath.LastIndexOf('\\');
            String PartName = FolderPath.Remove(0, NameID + 1);
            String XmlName = "SVT_MEDIA-TU" + PartName + ".XML";
            return File.Exists(FolderPath + "\\" + XmlName);
        }

        private void loadButton_Click(object sender, EventArgs e)
        {
            int Id = ConvertedFolderList.SelectedIndex;
            if (Id >= 0)
            {
                String FolderPath = FullFolderNamesCF[Id];
                int NameID = FolderPath.LastIndexOf('\\');
                String PartName = FolderPath.Remove(0, NameID + 1);
                String XmlName = "SVT_MEDIA-TU" + PartName + ".XML";
                ProcessHandler PrcHnd = new LoadingProcessHandler(Loadng2DBComplete, Id, FolderPath);
                PrcHnd.Command = "FlightDataBase " + FolderPath + " " + XmlName;
                PrcHnd.RunProcess();
            }
        }

        private void Loadng2DBComplete(int ExitCode, string FileName, ProcessHandler caller)
        {
            if (ExitCode == 0)
            {
                RefreshFlightTable();
            }
            else
            {
                MessageBox.Show("Loading to DB flight " + FileName + " was not successfull");
            }
        }

        private void RefreshButton_Click(object sender, EventArgs e)
        {
            lock (dbLoadedList)
            {
                RefreshFlightTable();
            }
        }

        public void RefreshFlightTable()
        {
            int n = dbLoadedList.Items.Count;
            for (int i = 0; i < n; i++)
            {
                dbLoadedList.Items.RemoveAt(0);
            }
            SqlConnection conn = null;
            SqlDataReader reader = null;
            try
            {
                conn =
                    new SqlConnection("Data Source = " + IPbox.Text + "; Initial Catalog = " + DBnameBox.Text + "; USER ID = admin; PASSWORD = 123; Connection Timeout = 20");
                conn.Open();
                SqlCommand command = new SqlCommand("SELECT Name FROM Flight");
                command.Connection = conn;
                reader = command.ExecuteReader();
                string FlName;
                while (reader.Read())
                {
                    FlName = reader.GetString(0);
                    dbLoadedList.Items.Add(FlName);
                }
                reader.Close();
                dbLoadedList.Refresh();
                conn.Close();
            }
            catch (SqlException)
            {
                MessageBox.Show("Unable to connect to DB!");
                if (conn != null)
                {
                    conn.Close();
                }
            }
        }

        public int GetFlightId(string FlightName)
        {
            int Id = -1;
            SqlConnection conn = null;
            SqlDataReader reader = null;
            try
            {
                conn =
                        new SqlConnection("Data Source = " + IPbox.Text + "; Initial Catalog = " + DBnameBox.Text + "; USER ID = admin; PASSWORD = 123; Connection Timeout = 20");
                conn.Open();
                SqlCommand command = new SqlCommand("SELECT Id FROM Flight WHERE Name = '" + FlightName + "'");
                command.Connection = conn;
                reader = command.ExecuteReader();
                while (reader.Read())
                {
                    Id = reader.GetInt32(0);
                }
                reader.Close();
                conn.Close();
            }
            catch (SqlException)
            {
                MessageBox.Show("Unable to connect to DB!");
                if (conn != null)
                {
                    conn.Close();
                }

            }
            return Id;
        }

        private void RemoveFileFromFullProcessing(string FileName)
        {
            if (FullProcessingBox.InvokeRequired)
            {
                stringDelegate sd = new stringDelegate(AddTextToListConvertedMMO);
                ConvertedFolderList.Invoke(sd, new object[] { FileName });
                return;
            }
            int Id = FullProcessingList.IndexOf(FileName);
            FullProcessingBox.Items.RemoveAt(Id);
            FullProcessingList.RemoveAt(Id);
            ProcessingInfo.RemoveAt(Id);
        }

        private void MMO2CF(string FileName)
        {
            //zipping MMO files
            string[] args = new string[2];
            BackgroundWorker _zipBW = new BackgroundWorker();
            _zipBW.DoWork += new DoWorkEventHandler(_zipBW_DoWork);
            args[0] = FileName;
            args[1] = args[0].Remove(args[0].Length - 4) + ".zip";
            _zipBW.RunWorkerAsync(args);

            //converting them to CF
            ProcessHandler PrcHnd = new PythonProcessHandler(CF2DB, ListConvMMO2XML.Count, FileName);   //new PythonProcessHandler(this, ListConvMMO2XML.Count, FullFileNamesMMO[Id]);
            PrcHnd.Command = "python Convert.py " + PrcHnd.FileName;
            PrcHnd.RunProcess();
        }

        private void FullProcessButton_Click(object sender, EventArgs e)
        {
            int Id = ProcessingFile.SelectedIndex;
            if (Id >= 0)
            {
                string FullFileName = FullFileNamesMMO[Id];
                RemoveTextFromMMOList((string)ProcessingFile.Items[Id]);
                FullProcessingList.Add(FullFileName);
                int NameID = FullFileName.LastIndexOf('\\');
                String PartName = FullFileName.Remove(0, NameID + 1);
                FullProcessingBox.Items.Add(PartName);
                ProcessingInfo.Add(PartName + " conversion to CF");
                MMO2CF(FullFileName);
            }
        }

        private void CF2DB(int ExitCode, string FileName, int Id, ProcessHandler caller)
        {
            if (ExitCode == 0)
            {
                Id = FullProcessingList.IndexOf(FileName);
                int NameID = FileName.LastIndexOf('\\');
                FileName = FileName.Remove(FileName.Length - 4);
                String PartName = FileName.Remove(0, NameID + 1);
                String XmlName = "SVT_MEDIA-TU" + PartName + ".XML";
                ProcessingInfo[Id] = "Flight " + FileName + " loading to DB";
                ProcessHandler PrcHnd = new LoadingProcessHandler(Raw2Vector, Id, FileName);
                PrcHnd.Command = "FlightDataBase " + FileName + " " + XmlName;
                PrcHnd.RunProcess();
            }
            else
            {
                MessageBox.Show("File " + FileName + " was not converted to CF");
                RemoveFileFromFullProcessing((FileName+".mmo"));
            }
        }

        public void Raw2Vector(int ExitCode, string FileName, ProcessHandler caller)
        {
            if (ExitCode == 0)
            {
                RefreshFlightTable();
                int NameID = FileName.LastIndexOf('\\');
                String PartName = FileName.Remove(0, NameID + 1);
                int Id = GetFlightId(PartName);
                PreprocessingProcessHandler PrcHnd = new PreprocessingProcessHandler(FinalizingFullLoop, Id, PartName);
                PrcHnd.Command = "ConvertorRaw2Vector " + Id.ToString();
                PrcHnd.RunProcess();
            }
            else
            {
                MessageBox.Show("Flight " + FileName + " was not loaded to DB.");
                RemoveFileFromFullProcessing((FileName+".mmo"));
            }
        }

        private void RefreshProcTable()
        {
            int n = ProcessedFlightsBox.Items.Count;
            for (int i = 0; i < n; i++)
            {
                ProcessedFlightsBox.Items.RemoveAt(0);
            }
            SqlConnection conn = null;
            SqlDataReader reader = null;
            try
            {
                conn =
                    new SqlConnection("Data Source = " + IPbox.Text + "; Initial Catalog = " + DBnameBox.Text + "; USER ID = admin; PASSWORD = 123; Connection Timeout = 20");
                conn.Open();
                SqlCommand command = new SqlCommand("SELECT Name FROM Flight WHERE Id IN (SELECT FlightId FROM ProcessedFlight)");
                command.Connection = conn;
                reader = command.ExecuteReader();
                string FlName;
                while (reader.Read())
                {
                    FlName = reader.GetString(0);
                    ProcessedFlightsBox.Items.Add(FlName);
                }
                ProcessedFlightsBox.Refresh();
                reader.Close();
                conn.Close();
            }
            catch (SqlException)
            {
                MessageBox.Show("Unable to connect to DB!");
                if (conn != null)
                {
                    conn.Close();
                }
            }
        }

        private void ProcRefresh_Click(object sender, EventArgs e)
        {
            RefreshProcTable();
        }

        private void dbLoadedList_SelectedIndexChanged(object sender, EventArgs e)
        {
            RefreshProcTable();
            int Id = dbLoadedList.SelectedIndex;
            if (Id > 0)
            {
                string SelectedFlight = (string)dbLoadedList.Items[Id];
                if (ProcessedFlightsBox.Items.Contains(SelectedFlight))
                {
                    label1.Text = "Converted";
                }
                else
                {
                    label1.Text = "Not converted";
                }
            }
        }

        public void FinalizingFullLoop(int ExitCode, string FileName, ProcessHandler caller)
        {
            if (ExitCode == 0)
            {
                RefreshProcTable();
            }
            else
            {
                MessageBox.Show("Flight " + FileName + " was not preprocessed.");
            }
        }

        private void PreProcbutton_Click(object sender, EventArgs e)
        {
            int Id = dbLoadedList.SelectedIndex;
            if (Id > 0)
            {
                String PartName = (string)dbLoadedList.Items[Id];
                int FlightId = GetFlightId(PartName);
                PreprocessingProcessHandler PrcHnd = new PreprocessingProcessHandler(FinalizingFullLoop, FlightId, PartName);
                PrcHnd.Command = "ConvertorRaw2Vector " + FlightId.ToString();
                PrcHnd.RunProcess();
            }
        }
    }
}
